import os
import time
import tempfile
import logging
from pathlib import Path
import fitz  # PyMuPDF
from PyPDF2 import PdfReader, PdfWriter, PdfMerger
from config import Config  # 从config.py导入配置类
from ..utils.logger import pdf_logger, extract_logger
from natsort import natsorted

# -------------------------- 工具函数：增强版文件/文件夹清理（处理占用问题） --------------------------
def safe_delete_file(file_path, max_retries=3, retry_interval=0.5):
    """
    安全删除文件：支持重试（应对临时占用），删除失败时记录详细日志
    :param file_path: 文件路径（Path对象或字符串）
    :param max_retries: 最大重试次数
    :param retry_interval: 重试间隔（秒）
    :return: True=删除成功，False=删除失败
    """
    file = Path(file_path)
    if not file.exists() or not file.is_file():
        # 这里先判断logger是否存在，避免未初始化时报错
        if 'extract_logger' in globals() and extract_logger is not None:
            extract_logger.debug(f"无需删除：文件不存在或不是文件 - {file}")
        return True
    
    for retry in range(max_retries):
        try:
            file.unlink()  # 删除文件
            if 'extract_logger' in globals() and extract_logger is not None:
                extract_logger.debug(f"文件删除成功（第{retry+1}次尝试）：{file.name}")
            return True
        except Exception as e:
            err_msg = f"文件删除失败（第{retry+1}次尝试）：{file}，错误：{str(e)}"
            if 'extract_logger' in globals() and extract_logger is not None:
                extract_logger.warning(err_msg)
            else:
                print(err_msg)  # 若logger未就绪，用print临时输出
            time.sleep(retry_interval)
    # 重试次数用完仍失败
    final_err = f"文件删除失败（已重试{max_retries}次）：{file}，可能被长期占用"
    if 'extract_logger' in globals() and extract_logger is not None:
        extract_logger.error(final_err)
    else:
        print(final_err)
    return False


def clear_folder(folder_path):
    """
    增强版文件夹清空：确保每个文件都被尝试删除，应对临时占用
    :param folder_path: 文件夹路径（Path对象或字符串）
    """
    folder = Path(folder_path)
    if not folder.exists() or not folder.is_dir():
        if 'extract_logger' in globals() and extract_logger is not None:
            extract_logger.debug(f"无需清空：文件夹不存在或不是目录 - {folder}")
        return
    
    if 'extract_logger' in globals() and extract_logger is not None:
        extract_logger.debug(f"开始清空文件夹：{folder}")
    # 先删文件（处理占用），再删子文件夹
    for item in folder.iterdir():
        if item.is_file():
            safe_delete_file(item)  # 调用安全删除函数
        elif item.is_dir():
            # 递归清空子文件夹，再删除空文件夹
            clear_folder(item)
            try:
                item.rmdir()
                if 'extract_logger' in globals() and extract_logger is not None:
                    extract_logger.debug(f"空文件夹删除成功：{item.name}")
            except Exception as e:
                err_msg = f"子文件夹删除失败（可能非空）：{item}，错误：{str(e)}"
                if 'extract_logger' in globals() and extract_logger is not None:
                    extract_logger.error(err_msg)
                else:
                    print(err_msg)
    if 'extract_logger' in globals() and extract_logger is not None:
        extract_logger.debug(f"文件夹清空完成：{folder}")


class Extract:
    """功能2：提取PDF中「含指定POSITION关键词且含'签名'」的页面，并合并为单个文件"""
    
    def run(self):
        """执行核心逻辑：遍历目标目录、筛选页面、提取合并、清理临时文件"""
        extract_logger.info("=" * 60)
        extract_logger.info("功能2启动：提取含指定关键词且含'签名'的PDF页面")
        extract_logger.info("=" * 60)
        
        try:
            temp_file_paths = []  # 存储提取页面的临时文件路径
            total_extracted_pages = 0  # 统计总提取页数
            # 1. 遍历目标源目录（SOURCE_DIR1），跳过指定文件夹
            extract_logger.debug(f"开始遍历目标源目录：{Config.SOURCE_DIR1}")
            # 确保文件夹和文件按照文件系统的原始顺序遍历
            for root_dir, sub_dirs, file_names in os.walk(Config.SOURCE_DIR1):
                # 跳过配置中指定的文件夹模糊匹配
                sub_dirs[:] = [d for d in sub_dirs if not any(keyword in d for keyword in Config.SKIP_FOLDERS)]
                # 按照Windows系统名称顺序排序文件夹
                sub_dirs[:] = natsorted(sub_dirs)
                # 按照Windows系统名称顺序排序文件
                file_names_sorted = natsorted(file_names)
                # 遍历排序后的文件列表
                for file_name in file_names_sorted:
                    if file_name.lower().endswith(".pdf"):
                        # 不再跳过包含"签字版"的文件，直接处理所有PDF文件
                        pdf_file_path = os.path.join(root_dir, file_name)
                        current_file_extracted = 0  # 统计当前文件提取的页数
                           
                        extract_logger.debug(f"开始处理PDF文件：{pdf_file_path}")
                        
                        # 3. 用PyMuPDF打开PDF，逐页读取文本并筛选
                        with fitz.open(pdf_file_path) as pdf_doc:
                            # 文件名检查：判断是否包含MAIN_DOCUMENT_KEYWORDS或SPECIAL_KEYWORDS_DVP
                            file_name_lower = file_name.lower()
                            is_special_file = any(kw.lower() in file_name_lower for kw in Config.MAIN_DOCUMENT_KEYWORDS)
                            is_special_file = is_special_file or any(kw.lower() in file_name_lower for kw in Config.SPECIAL_KEYWORDS_DVP)
                             
                            for page_index in range(len(pdf_doc)):
                                # 页面文本预处理：去空格、转小写（统一匹配标准）
                                page = pdf_doc.load_page(page_index)
                                page_text = page.get_text().replace(" ", "").lower()
                                 
                                # 筛选条件：
                                # 1. 对于特殊文件：需要同时满足「含POSITION关键词」和「含'审批页'字样」
                                # 2. 对于普通文件：只需要满足「含POSITION关键词」
                                has_position = any(
                                    kw.replace(" ", "").lower() in page_text
                                    for kw in Config.POSITION_KEYWORDS
                                )
                                 
                                # 根据文件类型确定筛选条件
                                if is_special_file:
                                    # 特殊文件需要同时有position关键词和'审批页'字样
                                    has_approval = "审批页" in page_text
                                    meet_condition = has_position and has_approval
                                else:
                                    # 普通文件只需要有position关键词
                                    meet_condition = has_position
                                 
                                # 满足条件则提取当前页
                                if meet_condition:
                                    # 创建临时文件（不自动删除，后缀为.pdf）
                                    with tempfile.NamedTemporaryFile(
                                        delete=False, suffix=".pdf"
                                    ) as temp_file:
                                        temp_file_path = temp_file.name
                                    
                                    # 用PyPDF2复制当前页到临时文件（确保资源释放）
                                    try:
                                        pdf_reader = PdfReader(pdf_file_path)
                                        pdf_writer = PdfWriter()
                                        pdf_writer.add_page(pdf_reader.pages[page_index])
                                        with open(temp_file_path, "wb") as temp_f:
                                            pdf_writer.write(temp_f)
                                        extract_logger.debug(f"临时页面生成：{os.path.basename(temp_file_path)}")
                                    except Exception as e:
                                        extract_logger.error(f"临时页面生成失败：{temp_file_path}，错误：{str(e)}")
                                        safe_delete_file(temp_file_path)  # 生成失败则删除临时文件
                                        continue
                                    
                                    # 记录临时文件路径和统计页数
                                    temp_file_paths.append(temp_file_path)
                                    total_extracted_pages += 1
                                    current_file_extracted += 1
                                    
                                    # 日志记录提取详情
                                    matched_kw = [
                                        kw for kw in Config.POSITION_KEYWORDS
                                        if kw.replace(" ", "").lower() in page_text
                                    ][0]
                                    extract_logger.info(
                                        f"✅ 提取成功 | 文件：{os.path.basename(pdf_file_path)} "
                                        f"| 页码：第{page_index + 1}页 | 匹配关键词：{matched_kw}"
                                    )
            
            # 5. 合并所有临时文件（若有提取结果）
            if temp_file_paths:
                extract_logger.info(f"\n📥 开始合并：共 {len(temp_file_paths)} 个提取页面")
                
                # 清空内部签字页文件夹 + 删除旧目标文件
                clear_folder(Config.INTERNAL_SIGN_DIR)
                output_dir = Path(Config.INTERNAL_SIGN_DIR)
                output_dir.mkdir(parents=True, exist_ok=True)
                final_pdf_path = output_dir / "内部待签字页.pdf"
                safe_delete_file(final_pdf_path)  # 双重保险：删除旧文件
                
                # 合并文件（确保资源释放）
                try:
                    with PdfMerger() as merger:
                        for temp_path in temp_file_paths:
                            if Path(temp_path).exists():
                                merger.append(temp_path)
                            else:
                                extract_logger.warning(f"临时文件不存在，跳过合并：{temp_path}")
                        final_abs_path = str(final_pdf_path.resolve())
                        merger.write(final_abs_path)
                    extract_logger.info(
                        f"📦 合并完成 | 最终文件：{final_abs_path} "
                        f"| 总提取页数：{total_extracted_pages}页"
                    )
                except Exception as e:
                    extract_logger.error(f"文件合并失败：{str(e)}")
                    safe_delete_file(final_pdf_path)
                    raise
                
                # 清理临时文件
                extract_logger.debug("\n🗑️  开始清理临时文件")
                for temp_path in temp_file_paths:
                    safe_delete_file(temp_path)
            
            # 无符合条件的页面时的处理
            else:
                extract_logger.info("\n❌ 未找到任何符合条件的页面（需含POSITION关键词且含'签名'）")
                clear_folder(Config.INTERNAL_SIGN_DIR)
            
            # 执行完成日志
            extract_logger.info("\n" + "=" * 60)
            extract_logger.info(f"功能2执行结束 | 累计提取有效页面：{total_extracted_pages}页")
            extract_logger.info("=" * 60)
            
            # 返回结果
            return (
                f"功能2执行完成！\n"
                f"📊 提取统计：{total_extracted_pages} 个符合条件的页面\n"
                f"📁 输出路径：{Config.INTERNAL_SIGN_DIR}/内部待签字页.pdf\n"
                f"📄 日志路径：{Config.LOG_DIR}/内部签字页操作日志.log（已清空新建）\n"
                f"⚠️  提示：若无法打开PDF，请检查文件是否被其他程序占用"
            )
        
        # 异常处理
        except Exception as err:
            error_msg = f"功能2执行失败：{str(err)}"
            extract_logger.error(error_msg, exc_info=True)
            # 清理临时文件和不完整文件
            for temp_path in temp_file_paths:
                safe_delete_file(temp_path)
            safe_delete_file(Path(Config.INTERNAL_SIGN_DIR) / "内部待签字页.pdf")
            return error_msg